package javacommon.base;

import java.io.Serializable;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Projections;
import org.springframework.dao.DataAccessException;
import org.springframework.transaction.annotation.Transactional;

/**
 * @author badqiu
 */
@Transactional
public abstract class BaseManager<E, PK extends Serializable> {

	protected Log log = LogFactory.getLog(getClass());

	protected abstract EntityDao getEntityDao();

	@Transactional(readOnly = true)
	public E getById(PK id) throws DataAccessException {
		return (E) getEntityDao().getById(id);
	}

	@Transactional(readOnly = true)
	public List<E> findAll() throws DataAccessException {
		return getEntityDao().findAll();
	}

	/** 根据id检查是否插入或是更新数据 */
	public void saveOrUpdate(E entity) throws DataAccessException {
		getEntityDao().saveOrUpdate(entity);
	}

	/** 插入数据 */
	public void save(E entity) throws DataAccessException {
		getEntityDao().save(entity);
		getEntityDao().flush();
	}

	public void removeById(PK id) throws DataAccessException {
		getEntityDao().deleteById(id);
	}

	public void update(E entity) throws DataAccessException {
		getEntityDao().update(entity);
	}

	@Transactional(readOnly = true)
	public boolean isUnique(E entity, String uniquePropertyNames)
			throws DataAccessException {
		return getEntityDao().isUnique(entity, uniquePropertyNames);
	}

	public List<E> findByCriteria(DetachedCriteria criteria) {
		return getEntityDao().findByCriteria(criteria);
	}

	public List<E> findByCriteria(DetachedCriteria criteria, int firstResult,
			int maxResults) {
		criteria.setProjection(null);
		return getEntityDao().findByCriteria(criteria, firstResult, maxResults);
	}

	public Object findUniqueByCriteria(DetachedCriteria criteria) {
		criteria.setProjection(null);
		List list = getEntityDao().findByCriteria(criteria);
		if (list != null && list.size() > 0) {
			return list.get(0);
		} else {
			return null;
		}
	}

	public int findByCriteriaCount(DetachedCriteria criteria) {
		criteria.setProjection(Projections.rowCount());
		return (Integer) getEntityDao().findByCriteria(criteria).get(0);
	}

	public int update(String hql) {
		return getEntityDao().update(hql);
	}

	public int remove(String hql) {
		return getEntityDao().update(hql);
	}

	public List<E> getHql(String hql){
		   return  getEntityDao().getHql(hql);
	   }
}
